#include <string.h>
#include <vector>
#include <iostream>
using std::cout;
using std::endl;
using std::vector;
using std::ostream;

class String
{
public:
    String(const char * pstr)
    : _pstr(new char[strlen(pstr) + 1]())
    {   
        cout << "String(const char *)" << endl;
        strcpy(_pstr, pstr);
    }

    //拷贝构造函数
    String(const String & rhs)
    : _pstr(new char[strlen(rhs._pstr) + 1]())
    {
        cout << "String(const String&)" << endl;
        strcpy(_pstr, rhs._pstr);
    }

    //赋值函数
    String & operator=(const String & rhs)
    {
        cout << "String & operator=(const String&)" << endl;
        if(this != & rhs) {
            delete [] _pstr;
            _pstr = new char[strlen(rhs._pstr) + 1]();
            strcpy(_pstr, rhs._pstr);
        }
        return * this;
    }


    //当传递右值时，
    //具有移动语义的函数会优先于具有复制控制语义函数的调用

    //移动构造函数
    String(String && rhs)
    : _pstr(rhs._pstr) //浅拷贝
    {
        rhs._pstr = nullptr;
        cout << "String(String&&)" << endl;
    }

    //移动赋值运算符函数
    String & operator=(String && rhs)
    {
        if(this != &rhs){
            cout << "String & operator=(String&&)" << endl;
            delete [] _pstr;
            _pstr = rhs._pstr;
            rhs._pstr = nullptr;
        }

        return *this;
    }

    ~String()
    {
        if(_pstr) {
            delete [] _pstr;
            _pstr = nullptr;
        }
        cout << "~String()" << endl;
     }

    friend ostream & operator<<(ostream & os, const String & rhs);

private:
    char * _pstr;
};
    
ostream & operator<<(ostream & os, const String & rhs)
{
    if(rhs._pstr)
        os << rhs._pstr;
    return os;
}

void test0()
{
    vector<String> strs;
    strs.reserve(2);
    strs.push_back("hello");

}

void test1()
{
    //右值引用可以绑定到右值
    String && ref = String("hello");
    cout << "ref:" << ref << endl;

    //右值引用可以单独识别出右值
    String str("world");
    //String && ref2 = str;//error
}

String && func()
{   return String("wuhan"); }

void test2()
{
    String str1("hello");
    cout << "str1:" << str1 << endl;

    str1 = String("world");
    cout << "str1:" << str1 << endl << endl;

    //当打印完str1之后，就不再需要它了
    //希望将str1的字符串内容转交给str2对象
    //
    //std::move可以显式的将一个左值转换为右值
    
    //std::move(str1);//没有任何效果

    //(String&&)str1;
    String str2 = std::move(str1);//函数传参时使用
    //String str2 = str1;
    //cout << "str2:" << str2 << endl;
    //当str1被显式转换成右值以后，是其内容被掏空了
    //其对象的生命周期还与原来是相同的
    cout << "str1:" << str1 << endl << endl;

    str2 = std::move(str2);
    cout << "str2:" << str2 << endl << endl;

    //&func();//右值引用是右值的情况
    String && ref = func();
    &ref;//ok 右值引用是左值的情况
}

String func1()
{
    String str1("wangdao");
    cout << "str1:" << str1 << endl;
    return str1;
}

void test3()
{
    func1();
}

String gstr("wuhan");

String func2()
{
    cout << "gstr:" << gstr << endl;
    return gstr;
}

void test4()
{
    func2();
}


int main()
{
    /* test0(); */
    /* test1(); */
    test2();
    /* test3(); */
    /* test4(); */
    return 0;
}

